﻿package bdz.projects.lavender.opsm.ui {
	import bdz.common.events.GenericEvent;
	import bdz.projects.lavender.opsm.model.FlipCollection;
	import bdz.projects.lavender.opsm.events.*;
	import bdz.projects.lavender.opsm.vo.ProductVO;
	import flash.display.BitmapData;
	import flash.display.MovieClip;
	import flash.events.Event;
	import flash.geom.Matrix;
	import flash.utils.*;
	import bdz.common.utils.ExecutionTime;
	/**
	 * ...
	 * @author Donald
	 */
	public class DisplayGrid extends MovieClip {
		
		
		private var _dataProvider:FlipCollection;
		
		private var _maxCols:int = 6;
		private var _maxRows:int = 12;
		private var _scaling:Number = .333333333;
		private var _fitToW:Number = 720;
		private var _fitToH:Number = 540;
		private var _baseW:Number = 360;
		private var _baseH:Number = 180;
		private var _gridRef:Array;
		private var _totalPages:int;
		private var _currentPage:int;
		private var _holder:MovieClip;
		
		private var _totalItems:int;
		
		public var origCols:int;
		public var origRows:int;
		
		private var _currentBitmap:BitmapData;
		
		private var _max:Number;
		private var _completed:Number = 0;
		
		private var _initialRendered:Boolean = false;
		
		private var _rendering:Boolean = false;
		private var _pagechange:Boolean = false;
		
		
		function DisplayGrid(dw:Number = -1, dh:Number = -1, mcols:Number = 6, mrows:Number = 9, scale:Number = .333333333) {
			_maxCols = mcols;
			_maxRows = mrows;
			_scaling = scale;
			
			if (dw != -1 && dh != -1) {
				_baseW = dw;
				_baseH = dh;
				_fitToW = Math.ceil(_baseW * _scaling) * _maxCols;
				_fitToH = Math.ceil(_baseH * _scaling) * _maxRows;
			}
			origCols = _maxCols = _fitToW / Math.ceil(_baseW * _scaling);
			origRows = _maxRows = _fitToH / Math.ceil(_baseH * _scaling);
			
			_currentPage = 1;
		}
		
		protected function checkNewScale():void {
			
			var average:Number = 100 - ((_totalItems / _dataProvider.length) * 100);
			trace("AVERAGE AMOUNT >> " + average);
			if (average < 31) {
				_scaling = .333333;
			}
			if (average > 80) {
				_scaling = 1;
			}
			if (Math.abs(average-50) <= 12.5) {
				_scaling = .666666;
			}
			//var scales:Array = [1, .666666, .33333];
			//_scaling = scales[Math.floor(Math.random() * scales.length)];
			
			_maxCols = _fitToW / Math.ceil(_baseW * _scaling);
			_maxRows = _fitToH / Math.ceil(_baseH * _scaling);
			
		}
	
		protected function onCollectionChanged(evt:FlipModelEvent):void {
			_totalItems = _dataProvider.length;
			_totalPages = Math.ceil(_totalItems / (_maxCols * _maxRows));
			render();
		}
		protected function refreshPageView():void {
			_pagechange = true;
			render();
		}
		
		protected function onCollectionFiltered(evt:FlipModelEvent):void {
			_currentPage = 1;
			_totalItems = _dataProvider.length;
			checkNewScale();
			_totalPages = Math.ceil(_totalItems / (_maxCols * _maxRows));
			render();
		}
		protected function clear():void {
			for each(var pv:ProductView in _gridRef) {
				removeChild(pv);
				
			}		
			_gridRef = new Array();
		}
		protected function onRendererComplete(evt:GenericEvent):void {
			if (_completed < maxItemsPerPage()-1) {
				_completed++;
			}else {	
				stage.invalidate();
				setTimeout(dispatchEvent, 100, new GenericEvent(GenericEvent.GENERATED, { pageChange:_pagechange } ));
				_pagechange = false;
				_rendering = false;
			}
		}
		protected function maxItemsPerPage():int {
			var retpage:Number = (_maxRows * _maxCols) * _currentPage;
			if (retpage > _dataProvider.length) {
				return _dataProvider.length;
			}
			return retpage;
		}
		protected function render():void {
			clear();
			_rendering = true;
			var startx:Number = 0;
			var starty:Number = 0;
			var i:int = -1 + ((_maxCols * _maxRows) * (_currentPage-1));	
			var iperpage:int = maxItemsPerPage();
			_completed = i+1;
			
			var del:Number = 0;
			
			while (++i < iperpage) {
				startx = (i - ((_maxCols * _maxRows) * (_currentPage-1))) % _maxCols;
				starty = Math.floor((i-((_maxCols * _maxRows) * (_currentPage-1))) / _maxCols);
				var pvo:ProductVO = _dataProvider[i];
				if (!pvo) break;
				
				var renderer:ProductView = new ProductView(_scaling);
				renderer.defaultWidth = _baseW;
				renderer.defaultHeight = _baseH;
				renderer.index = i;
				renderer.creationDelay = del;
				renderer.addEventListener(GenericEvent.COMPLETE, onRendererComplete);
				renderer.data = pvo;
				
				renderer.x = startx * Math.ceil(_baseW * _scaling);
				renderer.y = starty * Math.ceil(_baseH * _scaling);
				renderer.addEventListener(GenericEvent.CLICKED, onItemButtonActions);
				renderer.addEventListener(GenericEvent.ROLL_OVER, onItemButtonActions);
				renderer.addEventListener(GenericEvent.ROLL_OUT, onItemButtonActions);
				_gridRef[i] = addChild(renderer);
				del += .0001;	
			}
			if (!_initialRendered) {
				_initialRendered = true;
			}else {
				dispatchEvent(new GenericEvent(GenericEvent.PROGRESS));
			}
		}
		
		private function onItemButtonActions(evt:GenericEvent):void {
			dispatchEvent(new GenericEvent(evt.type, evt.target.data));
		}
		public function nextPage():void {
			if (_currentPage < _totalPages) {
				_currentPage++;
				refreshPageView();
			}
		}
		public function previousPage():void {
			if (_currentPage > 1) {
				_currentPage--;
				refreshPageView();
			}
		}
		public function gotoPage(n:int):void {
			if (n > 0 && n <= _totalPages) {
				_currentPage = n;
				refreshPageView();
			}
		}
		public function set dataProvider(dp:FlipCollection):void {
			if (_dataProvider) {
				_dataProvider.removeEventListener(FlipModelEvent.COLLECTION_CHANGED, onCollectionChanged);
				_dataProvider.removeEventListener(FlipModelEvent.COLLECTION_FILTERED, onCollectionFiltered);
				_dataProvider.removeEventListener(FlipModelEvent.COLLECTION_FILTER_CLEARED, onCollectionFiltered);
			}
			_dataProvider = dp;
			_dataProvider.addEventListener(FlipModelEvent.COLLECTION_CHANGED, onCollectionChanged);
			_dataProvider.addEventListener(FlipModelEvent.COLLECTION_FILTERED, onCollectionFiltered);
			_dataProvider.addEventListener(FlipModelEvent.COLLECTION_FILTER_CLEARED, onCollectionFiltered);
		}
		
		public function get dataProvider():FlipCollection {
			return _dataProvider;
		}
		public function get bitmap():BitmapData {
			if (_currentBitmap) {
				_currentBitmap.dispose();
			}
			_currentBitmap = new BitmapData(width, height, true, 0x00ffffff);
			_currentBitmap.draw(this);
			return _currentBitmap;
		}
		public function set maxCols(n:int):void {
			_maxCols = n;
		}
		public function get maxCols():int {
			return _maxCols;
		}
		public function set maxRows(n:int):void {
			_maxRows = n;
		}
		public function get maxRows():int {
			return _maxRows;
		}
		public function set scaling(n:Number):void {
			_scaling = n;
		}
		public function get scaling():Number {
			return _scaling;
		}
		public function get currentPage():int {
			return _currentPage;
		}
		public function get totalPages():int {
			return _totalPages;
		}
		public function set baseWidth(n:Number):void {
			_baseW = n;
		}
		public function get baseWidth():Number {
			return _baseW;
		}
		public function set baseHeight(n:Number):void {
			_baseH = n;
		}
		public function get baseHeight():Number {
			return _baseH;
		}
		public function set displayWidth(n:Number):void {
			_fitToW = n;
		}
		public function get displayWidth():Number {
			return _fitToW;
		}
		public function set displayHeight(n:Number):void {
			_fitToH = n;
		}
		public function get displayHeight():Number {
			return _fitToH;
		}
		
	}
	
}